﻿import sys, time;
import json

import bgtp.bgtp as bgtp
from platform.KA import super, KA
from platform.jutils import *
from platform.utilits import *

import games.XO.Rules.XOGameManager, games.SevenUP.Rules.SevenUPGameManager
gamesDict = {"XO": "games.XO.Rules.XOGameManager.XOGameManager", "7UP": "games.SevenUP.Rules.SevenUPGameManager.SevenUPGameManager"}

class GameServer(KA):	
	def __init__(this):
		this.name = USR_SERVER;
		super.__init__(this);
		this.stream = [];
		this.users = [];
		this.log = [];
		this.liba = null
	
	def start(this):
		print time.ctime();
		print "start";
		
		while true:
			while len(this.stream) == 0:
				time.sleep(0.01);	
				
			msg = this.stream.pop();		
			req = Request(msg);
			req = super.doRequest(this, req);
			this.returnResult(req);
			
			if (this.state == KA_0):
				break;
		this.stop();
	
	def stop(this):
		this.liba.stop();
		print "stop";
		print time.ctime();
		sys.exit();
	
	#// utilits
	def _doRequest(this, req):
		return eval("this." + req.type)(req);
	
	def returnResult(this, req):
		if (not req.isAns):
			req.who = this.name;
		fromWho = req.who;
		return_type = "return_" + req.type;	
		this.liba.sendTo(req.usr, fromWho + ";" + return_type + ";" + req.getAnswer());
	
	def _getSavePath(this, fileName):
		return "saves\\" + fileName + ".gm";
	
	def _sendMsgToUsrs(this, msgType):
		for usr in this.users:
			msg_to_send = {};
			msg_to_send[MSG_USR] = this.name;
			msg_to_send[MSG_TYPE] = "sendMsg";
			msg_body = {};
			msg_body["USER_NAME"] = usr;
			msg_body["MSG_BODY"] = {}
			msg_body["MSG_BODY"][MSG_TYPE] = msgType;
			msg_to_send[MSG_BODY] = json.dumps(msg_body);
			this.liba.mail(msg_to_send);
		
	def _sampleAnswer(this, req, ans):
		ans_ = {};
		ans_[ANS_VAL] = ans;
		return req.Answer(this, ans_);
	
	#//##########################################
	#// реализация конкретных действий КА
	def startServer(this, req):
		if (req.usr == this.name):
			this.liba.init();
			this.liba.setValue("timeout", 60 * 60);
			this.liba.subscribe({}, this.stream);
			this.liba.subscribe({}, 'stdout');
			this.liba.startServer();
			
			super.setState(this, KA_WORK);
			return this._sampleAnswer(req, true);
		return req;
	
	def stopServer(this, req):
		super.setState(this, KA_0)
		return this._sampleAnswer(req, true)	
	
	def hi(this, req):
		if (this.users.count(req.usr) == 0):
			this.users.append(req.usr);
		return this._sampleAnswer(req, true);
	
	def bye(this, req):
		return this._sampleAnswer(req, true);
	
	def exit(this, req):
		if (this.users.count(req.usr) > 0):		
			this.users.remove(req.usr);
		return this._sampleAnswer(req, true);
	
	def newGame(this, req):
		gameName = req.body["GAME_NAME"];
		if (gamesDict.keys().count(gameName) == 0):
			return this._sampleAnswer(req, [false, "no game this name"]);
		super.setState(this, KA_GAME);
		this.subKA = eval(gamesDict[gameName])(this.liba.mail);	
		
		this._sendMsgToUsrs("newGame");
		return this._sampleAnswer(req, true);
	
	def stopGame(this, req):
		this.game = null;
		super.setState(this, KA_WORK);
		this._sendMsgToUsrs("stopGame");
		return this._sampleAnswer(req, true);
	
	def sendMsg(this, req):
		this.liba.sendTo(req.body["USER_NAME"], req.usr + ";" + "msg" + ";" + json.dumps(req.body["MSG_BODY"]));
		return this._sampleAnswer(req, true);
	
	def getState(this, req):
		return this._sampleAnswer(req, this.state);
	
	def saveLog(this, req):
		f = open(req.body["LOG_FILE_NAME"] + ".log", "w");
		f.write(str(this.log));
		return this._sampleAnswer(req, true);	
	
	def getLog(this, req):
		if (req.body["LOG_FILE_NAME"]== ""):
			return this._sampleAnswer(req, this.log);
		else:
			f = open(req.body["LOG_FILE_NAME"]+ ".log", "r");
			return this._sampleAnswer(req, f.read());
	
	def saveGame(this, req):
		f = open(this._getSavePath(req.body["GAME_FILE_NAME"]), "w");
		f.write(this.subKA.getSituation(this.name));
		f.close();
		return this._sampleAnswer(req, true);
	
	def loadGame(this, req):
		gameName = req.body["GAME_NAME"];
		if (gamesDict.keys().count(gameName) == 0):
			return req.Answer(this, {ANS_VAL: false, ANS_TEXT: "no game this name"});
		f = open(this._getSavePath(req.body["GAME_FILE_NAME"]), "r");
		situation = f.read();
		f.close();
		
		super.setState(this, KA_GAME);	
		this.subKA = eval(gamesDict[gameName])(this.liba.mail);
		this.subKA.setSituation(situation);
		
		this._sendMsgToUsrs("newGame");
		return this._sampleAnswer(req, true);
	
	def timeout(this, req):
		this.stopServer(req);
		return this._sampleAnswer(req, true);
	
	def getSituation(this, req):
		if (this.state == KA_GAME):
			return this._sampleAnswer(req, this.subKA.getSituation(req.usr));
		else:
			return this._sampleAnswer(req, false);

def main():
	if (sys.platform.count("java") == 0):
		sys.setcheckinterval(1);
	s = GameServer();
	s.liba = bgtp.liba;
	s.stream.append({MSG_USR: s.name, MSG_TYPE: "startServer", MSG_BODY: ""});
	s.start();

if (__name__ == '__main__'):
	main()
